package demo.db.mybatisPlus.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.ximalaya.xdcs.dify.mapper", sqlSessionFactoryRef = "difySqlSessionFactory")
public class DifyConfig {

    private String jdbcUrl;
    private String username;
    private String password;

    @Value("${pg.dify.url}")
    public void setJdbcUrl(String jdbcUrl) {
        this.jdbcUrl = jdbcUrl;
    }

    @Value("${pg.dify.username}")
    public void setUsername(String username) {
        this.username = username;
    }

    @Value("${pg.dify.password}")
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * 初始化数据源
     *
     * @return
     */
    @Bean(name = "difyDataSource")
    public DruidDataSource difyDataSource() {
        DruidDataSource ds = new DruidDataSource();
        /* 配置这个属性的意义在于，如果存在多个数据源，监控的时候可以通过名字来区分开来。 */
        ds.setName("dify_ds");
        ds.setDriverClassName("org.postgresql.Driver");
        ds.setUrl(jdbcUrl);
        ds.setUsername(username);
        ds.setPassword(password);
        /* 配置初始化大小、最小、最大 */
        /* 初始化时建立物理连接的个数。初始化发生在显示调用init方法，或者第一次getConnection时 */
        ds.setInitialSize(1);
        /* 最小连接池数量 */
        ds.setMinIdle(1);
        /* 最大连接池数量 */
        ds.setMaxActive(5);
        /*
         * 获取连接时最大等待时间，单位毫秒。配置了maxWait之后，缺省启用公平锁，并发效率会有所下降，
         * 如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
         */
        ds.setMaxWait(2000);
        /**
         * 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒. 有两个含义：
         * <li> 1) Destroy线程会检测连接的间隔时间
         * <li>2) testWhileIdle的判断依据，详细看testWhileIdle属性的说明
         */
        ds.setTimeBetweenEvictionRunsMillis(60000);
        /* 配置一个连接在池中最小生存的时间，单位是毫秒 */
        ds.setMinEvictableIdleTimeMillis(300_000);
        ds.setTestWhileIdle(true);
        /* 这里建议配置为TRUE，防止取到的连接不可用 */
        ds.setTestOnBorrow(true);
        ds.setTestOnReturn(false);
        /*
         * 验证连接有效与否的SQL，不同的数据配置不同
         * .如果validationQuery为null，testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
         */
        ds.setValidationQuery("select 1");
        return ds;
    }


    @Bean(name = "difySqlSessionFactory")
    public SqlSessionFactory difySessionFactoryBean(@Qualifier("difyDataSource") DataSource dataSource)
            throws Exception {
        MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mybatis/dify/*.xml"));
        factory.setTypeAliasesPackage("com.ximalaya.xdcs.dify.pojo");
        return factory.getObject();
    }

    @Bean(name = "difyTransactionManager")
    public DataSourceTransactionManager difyTransactionManager(@Qualifier("difyDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
